#pragma once
#include "Shader.h"
#include "Buffer.h"
#include "Texture2D.h"

namespace Nitro::Renderer {

enum PolygonMode
{
    Point = 0x1B00,
    Line = 0x1B01,
    Fill = 0x1B02,
};

enum DrawMode
{
    Points = 0x0000,
    Lines = 0x0001,
    Triangles = 0x0004,
    TriangleStrip = 0x005,
    TriangleFan = 0x0006,
};

struct PipelineDescriptor
{
    Shader vertexShader, fragmentShader;
    DrawMode drawMode = Triangles;
};

struct Pipeline
{
    bool hasReport();
    std::string getReport();
    void activate();

    inline int getUniformLocation(const char* name);
    template <typename T>
    inline void setUniform(const char* name, const T& value);
    template <typename T>
    inline void setUniform(int location, const T& value);
    template <typename... T>
    inline void setUniform(const char* name, T...);
    template <typename... T>
    inline void setUniform(int location, T...);

    void draw(int first, size_t count);
    void drawIndexed(const void* first, size_t count);

    static void setIndexBuffer(Buffer indexBuffer);
    static void setVertexBuffer(Buffer vertexBuffer);

    uint32_t id = 0;
    DrawMode drawMode;
};

Pipeline CreatePipeline(const PipelineDescriptor& desc);

}; // namespace Nitro::Renderer

#include "Uniform.inl"